package com.crpc.common.utils.zookeeper;

import com.crpc.common.constant.Constant;
import com.crpc.common.crpcEnum.CrpcExceptionEnums;
import com.crpc.common.exception.CrpcException;
import lombok.extern.slf4j.Slf4j;
import org.apache.zookeeper.*;

import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * @author CLOUD
 * @version 1.0
 * @description:
 * @date 2023/9/7 19:46
 */
@Slf4j
public class ZookeeperUtils {
    /**
     * 查询一个节点的子元素
     */
    public static List<String> getChildren(ZooKeeper zooKeeper, String serviceNode, Watcher watcher) {
        try {
            return zooKeeper.getChildren(serviceNode, watcher);
        } catch (KeeperException | InterruptedException e) {
            log.error("获取节点【{}】的子元素时发生异常.", serviceNode, e);
            e.printStackTrace();
            throw new CrpcException(CrpcExceptionEnums.ZOOKEEPER_ERROR);
        }
    }

    //不存在返回false ,存在返回true
    public static boolean exists(ZooKeeper zooKeeper, String node, Watcher watcher) {
        try {
            return zooKeeper.exists(node, watcher) != null;
        } catch (Exception e) {
            log.error("判断节点{}是否存在", node, e);
            e.printStackTrace();
            throw new CrpcException(CrpcExceptionEnums.ZOOKEEPER_ERROR);
        }
    }

    //关闭zookeeper的方法
    public static void close(ZooKeeper zooKeeper) {
        try {
            zooKeeper.close();
        } catch (InterruptedException e) {
            log.error("关闭zookeeper时发生问题：", e);
            e.printStackTrace();
            throw new CrpcException(CrpcExceptionEnums.ZOOKEEPER_ERROR);
        }
    }

    public static Boolean createNode(ZookeeperNode node, ZooKeeper zooKeeper, Watcher watcher, CreateMode createMode) {
        try {
            if (zooKeeper.exists(node.getNodePath(), watcher) == null) {
                String s = zooKeeper.create(node.getNodePath(), node.getData(), ZooDefs.Ids.OPEN_ACL_UNSAFE, createMode);
                log.info("节点创建成功：{}", s);
                return true;
            } else {
                log.info("节点已经存在：{}", node);
            }

        } catch (Exception e) {
            log.error("创建基础目录节点时,发生异常======>{}", e.getMessage());
            e.printStackTrace();
            throw new CrpcException(CrpcExceptionEnums.ZOOKEEPER_ERROR);
        }
        return false;
    }

    public static ZooKeeper createZooKeeper(String connectString, int timeout) {
        CountDownLatch countDownLatch = new CountDownLatch(1);
        try {
            final ZooKeeper zooKeeper = new ZooKeeper(connectString, timeout, event -> {
                if (event.getState().equals(Watcher.Event.KeeperState.SyncConnected)) {
                    log.info("===============客户端已经连接成功===============");
                    countDownLatch.countDown();
                }
            });
            countDownLatch.await();
            //定义节点和数据
            return zooKeeper;
        } catch (Exception e) {
            log.error("创建zookeeper时发生异常=====>{}", e.getMessage());
            e.printStackTrace();
            throw new CrpcException(CrpcExceptionEnums.ZOOKEEPER_ERROR);
        }
    }

    public static ZooKeeper createZooKeeper() {
        String connectString = Constant.DEFAULT_ZK_CONNECT;
        return createZooKeeper(connectString, Constant.DEFAULT_TIME_OUT);
    }
}
